/*
 * Copyright (c) Jan Šlahora (${USER}) - 2011.
 * Created in IntelliJ IDEA 10.5
 */

package GUIComponents;

import javax.swing.*;
import javax.swing.event.TableModelListener;
import javax.swing.table.TableModel;
import javax.swing.table.TableRowSorter;
import java.lang.reflect.Array;
import java.text.DecimalFormat;
import java.util.Arrays;
import java.util.HashMap;
import statistics.*;

/*
*   File Tabulka 
*   in package GUIComponents
*   was created by slaha
*   on 30.11.11 at 17:31.
*
*/
public class Tabulka {
  JTable table = null;
  long soucet = 0;
  Poisson p;
  Object[][] data;

  public Tabulka(String[] jmenaSloupcu, HashMap hashMap, boolean sort) {
    soucet = secti(hashMap);
    data = dejMatici(hashMap);
    if (jmenaSloupcu == null) {
      jmenaSloupcu = new String[data[0].length];
      for (int i = 0; i < data[0].length; i++) {
        jmenaSloupcu[i] = Integer.toString(i);
      }
    }
    TableModel model = getModel(jmenaSloupcu, data);
    table= new JTable(model);
    if (sort) {
      TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
      table.setRowSorter(sorter);
    }
  }

  public Tabulka(String[] jmenaSloupcu, HashMap hashMap) {
    this(jmenaSloupcu, hashMap, false);
  }
  public Tabulka(JTable t) {
    Object[] sloupec0 = dejSloupec(t, 0);
    Object[] sloupec1 = dejSloupec(t, 1);

    try {
      Integer.parseInt(sloupec0[0].toString());
      this.p = new Poisson(sloupec0, sloupec1);
      soucet = secti(sloupec1);
      String[] hlava = {"Počet", "Četnost"};
      TableModel model = getModel(hlava, dejMaticiPravdepodobnosti(sloupec0, sloupec1, Pravdepodobnosti.Poisson));
      table = new JTable(model);
    } catch (Exception ex){
      table = null;
    }
  }

  public Tabulka(JTable t, double lambda) {
    Object[] sloupec0 = dejSloupec(t, 0);
    Object[] sloupec1 = dejSloupec(t, 1);
    this.p = new Poisson(sloupec0, sloupec1);
    soucet = secti(sloupec1);
    String[] hlava = {"Počet", "Četnost"};
    if (sloupec0[0] instanceof Integer) {
      TableModel model = getModel(hlava, dejMaticiPravdepodobnosti(sloupec0, sloupec1, Pravdepodobnosti.Poisson));
      table = new JTable(model);
      TableRowSorter<TableModel> sorter = new TableRowSorter<TableModel>(model);
      table.setRowSorter(null);
    } else {
      table = null;
    }
  }

  public JTable getTable() {
    return table;
  }

  private Object[][] dejMatici(JTable t) {
    TableModel dtm = (TableModel) t.getModel();
    int nRow = dtm.getRowCount(), nCol = dtm.getColumnCount();
    Object[][] tableData = new Object[nRow][nCol];
    for (int i = 0; i < nRow; i++)
      for (int j = 0; j < nCol; j++)
        tableData[i][j] = dtm.getValueAt(i, j);
    return tableData;
  }

  private Object[][] dejMatici(HashMap hm) {
    

    Object[][] data = new Object[hm.keySet().size()][3];
    int i = 0;

    char ch = 1;
    for (Object o : hm.keySet()) {
      data[i][0] = o.toString();

      if (o.equals(ch)) {
        data[i][0] = "ch";
      }
      
      data[i][1] = hm.get(o);

      double prav = ((double) (new Double(data[i][1].toString()) / (double) soucet));
      prav = (Math.round((prav * 10000)));
      prav /= 10000;
      data[i][2] = Double.toString(prav);
      i++;
    }

    return data;
  }

  private Object[] dejSloupec(JTable t, int sloupec) {
    TableModel dtm = (TableModel) t.getModel();
    int nRow = dtm.getRowCount(), nCol = dtm.getColumnCount();
    Object[] tableData = new Object[nRow];
    for (int i = 0; i < nRow; i++)
        tableData[i] = dtm.getValueAt(i, sloupec);
    return tableData;
  }

  private Object[][] dejMaticiPravdepodobnosti(Object[] hodnoty, Object[] pocty, Pravdepodobnosti rozdeleni) {

    Object[][] data = new Object[hodnoty.length][2];
    int i = 0;
    double poisson = -1;

    for (Object o : hodnoty) {
      try {
        poisson = p.poissonovoRozdeleni(new Integer(o.toString()));
      } catch (Exception e) {
        data[i][0] = poisson;
        data[i][1] = poisson;
        e.printStackTrace();
      }
      //poisson = (Math.round((poisson * 10000)));
      //poisson/=10000;
      DecimalFormat df = new DecimalFormat("#.###############");
      // data[i][1] = Double.toString(poisson);
      data[i][1] = df.format(poisson);
      double prav = (double) (poisson * soucet);
      //data[i][0] = Double.toString(prav);
      data[i][0] = df.format(prav);
      i++;
    }
    return data;
  }

  private long secti(HashMap hm) {
    long s = 0;
    for (Object o : hm.values()) {
      s += new Integer(o.toString());
    }
    return s;
  }

  private long secti(Object[] p) {
    long s = 0;
    for (Object o : p) {
      s += new Integer(o.toString());
    }
    return s;
  }

  public Poisson getP() {
    return p;
  }

  public Object[][] getData() {
    return data;
  }

  private TableModel getModel(final String[] jmenaSloupcu, final Object[][] hashMap) {
    return new TableModel() {

      @Override
      public int getRowCount() {
        return hashMap.length;
      }

      @Override
      public int getColumnCount() {
        return jmenaSloupcu.length;
      }

      @Override
      public String getColumnName(int columnIndex) {
        return jmenaSloupcu[columnIndex].toString();  //To change body of implemented methods use File | Settings | File Templates.
      }

      @Override
      public Class<?> getColumnClass(int columnIndex) {
        return getValueAt(0,columnIndex).getClass();  //To change body of implemented methods use File | Settings | File Templates.
      }

      @Override
      public boolean isCellEditable(int rowIndex, int columnIndex) {
        return false;
      }

      @Override
      public Object getValueAt(int rowIndex, int columnIndex) {
        return hashMap[rowIndex][columnIndex];  //To change body of implemented methods use File | Settings | File Templates.
      }

      @Override
      public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
      }

      @Override
      public void addTableModelListener(TableModelListener l) {

      }

      @Override
      public void removeTableModelListener(TableModelListener l) {
        //To change body of implemented methods use File | Settings | File Templates.
      }
    };
  }
}
